


Function.prototype.myCall = function (ctx) {
  if (typeof this !== 'function') {
    throw new TypeError('is not a function');
  }
  ctx = Object(ctx) || window;
  ctx.fn = this;
  let args = []
  for (let i = 1; i < this.length; i++) {
    args.push('arguments[' + i + ']');

  }
  let res = eval('ctx.fn(' + args + ")");
  delete ctx.fn;
  return res;
}
Function.prototype.myApp = function (ctx, arg1) {
  if (typeof this !== 'function') {
    throw new TypeError('is not a function');
  }
  ctx = Object(ctx) || window;
  ctx.fn = this;
  if (!args.length) {
    ctx.fn();
    delete ctx.fn;
    return

  }
  let res = eval('ctx.fn(' + args + ')');
  delete ctx.fn;
  return res;
}



// function mockNew() {
//   let Constructor = [].shift.call(arguments);
//   let obj = {};
//   obj.__proto__ = Constructor.prototype;
//   let res = Constructor.apply(obj, arguments);
//   return res instanceof Object ? res : obj;
// }





Function.prototype.myBind = function (ctx) {
  if (typeof this !== 'function') {
    throw new TypeError('is a not function')
  }
  const that = this;
  let bindargs = Array.prototype.slice.call(arguments, 1);
  function Fn() { };
  function bindFn() {
    const args = Array.prototype.slice.call(arguments);
    that.apply(this instanceof bindFn ? this : ctx, bindargs.concat(args));
  }
  Fn.prototype = that.prototype;
  bindFn.prototype = new Fn();
  return bindFn;
}